#ifndef __SYMBOLES_H
#define __SYMBOLES_H

enum Type {
    VOID,
    INT,
    CHAR
} ;

struct SType {
    enum Type ssType ;
    int ssConst ;
    struct SType *ssNextArg ;
} ;

/* Compare 2 types. */
int cmpType (const struct SType *t1, const struct SType *t2) ;

struct Symbol {
    int sAddr ;
    char *sName ;
    int sBlockLevel ;
    struct SType *sType ;
    int sInit ;
    int sUsed ;
    struct Symbol *sNext ;
} ;

#define SYM_REDEFINED 1
#define SYM_UNDEFINED 2
#define SYM_CONSTANT  3

/* Crée un symbole correspondant à la fonction "name" et le retourne. */
struct Symbol *createFunctionSymbol (char const * const name, struct SType type, struct SType *args) ;

/* Crée un symbole correspondant à la variable "name" et le retourne. */
struct Symbol *createVariableSymbol (char const * const name, int blockLevel, struct SType type) ;

/* Libère le symbole pointé par sym. 
   ATTENTION : Ne doit pas être utilisé sur des symboles retournés par getSymbole. */
void freeSymbol (struct Symbol *sym) ;

/* Ajoute un symbole à la table si celui si n'existe pas, retourne 0 si tout s'est bien passé. */
int addSymbol (struct Symbol *sym) ; 

/* Retourne le symbole correspond à name au niveau blockLevel, ou NULL si il n'existe pas. */
struct Symbol *getSymbolAtLevel (char const * const name, int blockLevel) ;

/* Retourne le symbole correspond à name, ou NULL si il n'existe pas. */
struct Symbol *getSymbolUnderLevel (char const * const name, int blockLevel) ;

/* Retourne le symbole correspond à la fonction nommée "name", ou NULL si il n'existe pas. */
struct Symbol *getFunctionSymbol (char const * const name) ;

/* Retourne 1 si le symbole correspond à name existe au niveau blockLevel, 0 sinon. */
int isSymbolAtLevel (char const * const name, int blockLevel) ;

/* Retourne 1 si le symbole correspond à name existe, 0 sinon. */
int isSymbolUnderLevel (char const * const name, int blockLevel) ;

/* Retourne la taille actuelle (en octets) de l'ensemble des symboles. */
int getTotalSymbolSize (void) ;

/* Supprime tous les symboles de niveau level si level est le plus haut niveau de la liste,
   ne fait rien sinon.
   Si unused n'est pas NULL, unused pointera sur le premier symbole d'une liste des symboles
   inutilisés.
   Retourne la taille (en octets) de symboles supprimés. 
*/
int removeMaxLevelSymbols (int level, struct Symbol **unused) ;

#endif
